#ifndef __EVENTLOOPTHREAD_H__
#define __EVENTLOOPTHREAD_H__

#include "Spark/Net/EventLoop.h"
#include <memory>
#include <mutex>
#include <condition_variable>

class EventLoopThread : public NonCopyable
{
  public:
    explicit EventLoopThread(std::string threadName = "EventLoopThread");
    ~EventLoopThread();

    /**
     * @brief Wait for the event loop to exit.
     * @note This method blocks the current thread until the event loop exits.
     */
    void wait();

    /**
     * @brief Get the pointer of the event loop of the thread.
     *
     * @return EventLoop*
     */
    EventLoop *getLoop() const
    {
        return loop_;
    }

    /**
     * @brief Run the event loop of the thread. This method doesn't block the
     * current thread.
     *
     */
    EventLoop *run();

    bool started() const
    {
        return started_;
    }

  private:
    EventLoop *loop_;
    std::string loopThreadName_;
    void routine();
    std::mutex mutex_;
    std::condition_variable cond_;
    std::once_flag once_;
    bool started_{false};
    std::unique_ptr<std::thread> thread_;
};

#endif  // __EVENTLOOPTHREAD_H__